Skip to content

[deps] update expression-engine dependencies while retaining Math.js … - #37

Merged
mwasiluk merged 1 commit into
SilverDecisions:modernizefrom
mwasiluk:deps/non-mathjs-updates
Nov 4, 2026
Merged

mwasiluk merged 1 commit into
SilverDecisions:modernizefrom
mwasiluk:deps/non-mathjs-updates

Conversation

@mwasiluk

@mwasiluk mwasiluk commented Nov 4, 2026

Copy link
Copy Markdown
Member

Summary

Dependency update for the expression engine without changing Math.js or expression semantics. Base: modernize at d00e0e9 (B merged). package.json is unchanged; only package-lock.json, README.md and CHANGELOG.md change. dist/ is not rebuilt (release task).

Math.js stays at exactly 9.5.0. Its dependencies that define expression results keep their locked versions.

Version changes (lockfile)

Package Before After Where Bundled
@babel/runtime 7.15.4 7.29.10 Math.js dependency yes, both bundles (helpers)
regenerator-runtime (under @babel/runtime) 0.13.9 removed @babel/runtime 7.15 dependency was in both bundles; now @babel/runtime/helpers/regenerator*
lodash 4.17.21 4.18.1 sd-utils dependency standalone bundle
loglevel 1.7.1 1.9.2 sd-utils dependency standalone bundle
rollup (+ @rollup/rollup-* binaries) 4.67.3 4.67.5 dev no
@napi-rs/lzma-linux-x64-gnu 1.5.1 removed dev, optional dependency of rollup 4.67.3 no
baseline-browser-mapping, electron-to-chromium, ip-address, is-core-module, resolve, semver 6 / 5 / 7.8 (nested) patch patch dev no
lodash under release-it (hoisted 4.17.21) 4.17.21, nested dev; release-it 14 pins it exactly no

Runtime tree after the change: [email protected] (@babel/[email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected]), [email protected], [email protected] ([email protected], [email protected]).

Not updated, with reasons

  • Math.js dependencies that define results. complex.js 2.0.15 (2.4.3 available), decimal.js 10.3.1 (10.6.0), fraction.js 4.1.1 (4.3.7) and typed-function 2.0.0 (2.1.0) keep their locked versions.
    • They have no advisories, and they determine numbers, Fractions, BigNumbers, complex results and function dispatch.
    • complex.js 2.4.x is not ES5: dist/complex.js uses const, dist/complex.min.js uses let. 2.3.0 is still ES5.
    • A fresh install of the tarball (no lockfile) resolves them from the Math.js ranges and gets the newest versions. test:build reports this as info full consumer bundle is not ES5 ... [email protected]. It did so before this change as well.
    • The consumers' lockfiles (SilverDecisions, sd-computations 0.6.1) pin complex.js 2.0.15 and fraction.js 4.1.2.
  • Babel 6 plugins (transform-class-properties, transform-object-assign, transform-builtin-extend). They must stay installed.
    • The browserify.transform field of sd-utils 0.1.15 names them, in both the published version and its modernize branch 2a3af7c. The build, the Jasmine specs and consumers compile sd-utils with that field.
    • Reproduction: removing the three packages fails npm run build in the standalone bundle with Cannot find package 'babel-plugin-transform-class-properties', raised while compiling sd-utils.
    • This package's own sources compile to identical code with a Babel 7-only variant of the field (@babel/preset-env + assumptions.setPublicClassFields). Changing only this package's field gives consumers nothing while sd-utils still needs the plugins, so the field is unchanged here.
    • This should be one coordinated change across sd-utils, sd-model, this package and the consumers (whose lockfiles hold Babel 7.15).
  • release-it 14.14.3: the last 14.x release; it pins most of its vulnerable dependencies exactly. Major migration belongs to the release stage. release-it was not run.
  • jasmine 6.3.0: jasmine 7.0.0 accepts the same glob range (^10 … ^13), so the glob advisory stays either way. No reason for a major.
  • browserify 17.0.1, @rollup/plugin-node-resolve 16.0.3: already the latest. Their advisories (glob 7, crypto-browserify/elliptic; deepmerge) have no fixed release in range.
  • Babel 8: out of scope.

Audit (npm audit, registry state 2026-11-04)

Before After
runtime (--omit=dev) 2 (lodash high, @babel/runtime moderate) 0
all 49 (10 critical, 9 high, 18 moderate, 12 low) 48 (10 critical, 9 high, 17 moderate, 12 low)

All remaining findings are development tooling, none ends up in a bundle:

  • release-it 14 and its pinned dependencies: about 31 entries, including the remaining lodash and semver highs in node_modules/release-it/node_modules;
  • the Babel 6 plugins (babel-traverse/babel-template, critical);
  • browserify 17;
  • jasmine (glob/minimatch);
  • @rollup/plugin-node-resolve (deepmerge).

Contracts kept

  • Same exports, entry points (main, index.js, standalone.index.js, src/*), browserify.transform, bundle formats and globals.
  • Tarball: the same 44 files. Only the dist/ files, README and CHANGELOG differ.
  • ES5 in all four bundles.
  • Global surface checked in a vm context. The standalone bundles define SilverDecisions and regeneratorRuntime before and after. The module bundles define require.

Bundled modules (from the source maps): the same set except @babel/runtime. regenerator-runtime/runtime.js is gone and 11 helpers are added (toPrimitive, toPropertyKey, regenerator*, OverloadYield).

File B (fresh build) D Δ
dist/sd-expression-engine.js 9 543 246 9 510 117 −33 129
dist/sd-expression-engine.min.js 952 365 952 733 +368
dist/standalone/sd-expression-engine.js 11 471 452 11 451 652 −19 800
dist/standalone/sd-expression-engine.min.js 1 040 543 1 041 631 +1 088

Verification

Environment: Linux, Node 22.22.0 / npm 10.9.4 and Node 24.22.2 / npm 11.19.1. Every run used an isolated copy.

Base d00e0e9 (Node 22):

  • npm test on the committed 0.1.17 dist/ and the sources: all five contract targets passed; Jasmine 11 specs, 0 failures.
  • npm run test:build: all build checks passed.

This branch 20a1b49:

  • npm run test:build on Node 22 and on Node 24: all build checks passed. This covers:
    • npm ci, build without warnings, ES5, source maps;
    • contract tests on the four fresh bundles (standalone 60 pass / 3 skipped, module 62 / 1) and on the sources (59 / 4); Jasmine 11 / 0;
    • npm pack installed into an empty browserify 17 + babelify 10 consumer with --no-package-lock, with contract tests on its bundle and on the installed dist;
    • the syntax-error exit code check.
  • npm test (committed dist + sources): passed.
  • npm pack --dry-run: 44 files, 5.7 MB.
  • Differential evaluation, base fresh dist vs this branch, standalone and module bundles:
    • corpus: 262 expressions (fixture code and payoffs, number helpers, Fraction/BigNumber/complex values, sd-random distributions with a seeded Math.random);
    • each evaluated with asNumber true and false, plus validate;
    • 0 differences. Math.js random() was excluded: it is seeded by its own entropy and differs between two runs of the same bundle.
    • The committed 0.1.17 dist vs this branch also gives 0 differences.

Unreleased sd-utils / sd-random (modernize 2a3af7c / 96af2c9, fresh builds in isolated copies):

  • Tarballs: sd-utils-0.1.15.tgz sha256 eaf0a24b…97c5, sd-random-0.1.4.tgz sha256 956927ef…4815.
  • node scripts/check-build.js --sd-utils=<tgz> --sd-random=<tgz>: all build checks passed. package.json and the lockfile are not changed.

Consumers. Tarballs were installed with npm install --no-save into copies; package.json / package-lock.json were checked unchanged.

  • Consumer copies:
    • sd-computations 5bcba47 (0.6.1, npm ci);
    • SilverDecisions 2f77351 (its lockfile is out of sync with package.json upstream, so the copy was installed with npm install earlier; Babel fix of C not applied).
  • Variants:
    • B: fresh tarball of d00e0e9;
    • D: fresh tarball of 20a1b49, sha256 01f3bf10…ff80;
    • D + the modernized sd-utils/sd-random tarballs.
Consumer B D D + modernized sd-utils/sd-random
sd-computations: gulp build + Karma (Chrome headless; includes the "IDB with worker" specs, where a real Web Worker loads dist/sd-expression-engine.js with importScripts) 196/196 196/196 196/196
SilverDecisions: gulp build (browserify/babelify of sd-expression-engine/src) + Karma 37/37 37/37 37/37
SilverDecisions app scenarios (Playwright, demo/index.html with its job worker, seeded RNG; 13 saved diagrams opened, recomputed, saved and reopened; an edited diagram with code, a code error and its fix; tornado, spider, sensitivity analysis and probabilistic sensitivity analysis with sd-random distributions) baseline no differences no differences

Not run:

  • Windows (no local environment; the CI windows-smoke job runs on this PR).
  • A real browser for the dist bundles outside the consumers above.
  • release-it (not run, not even as a dry run).

Found while testing, not changed here

  • Minified module bundles of the Rollup builds leak globals (B, also sd-utils/sd-random modernize; not a dependency issue, so not fixed here).
    • @rollup/plugin-terser sets toplevel: true for format: 'cjs'. dist/sd-expression-engine.min.js therefore starts with var e,r,t;require=(…), and the require wrapper keeps its cache and factories in those globals.
    • Loading two such files into one scope breaks the chain: the modernized sd-utils.min.js + sd-random.min.js + this .min.js give r is not a function.
    • The 0.1.17 browserify builds and the plain .js files are not affected, and the known consumers load the plain files.
    • Suggested fix before a release: terser({toplevel: false}) for the cjs outputs in all four repositories, with a test that loads the .min.js module bundles together.
  • The plain module bundle is not byte-reproducible between builds. Rollup's CommonJS helper names vary (src$1 / copy); the code is equivalent.
  • sd-random 0.1.4: Gamma(alpha > 1) throws u is not defined. It is fixed on sd-random modernize (checked with the D module bundle).

🤖 Generated with Claude Code

…9.5.0

Locked versions within the existing ranges: @babel/runtime 7.29.10 (Math.js;
regenerator-runtime 0.13.9 dropped), lodash 4.18.1 and loglevel 1.9.2 (sd-utils),
Rollup 4.67.5 and other development packages. package.json is unchanged.

Math.js 9.5.0 and its numeric dependencies (complex.js, decimal.js, fraction.js,
typed-function) keep their locked versions. The Babel 6 plugins stay because the
browserify.transform of sd-utils 0.1.15 names them. release-it 14.14.3 is the
last 14.x release.
@mwasiluk
mwasiluk merged commit 7227ebd into SilverDecisions:modernize Nov 4, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants